/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package fr.sorbonne.soa.lib;

import fr.sorbonne.soa.entity.Customerorder;
import fr.sorbonne.soa.entity.Manufacturerinfo;
import fr.sorbonne.soa.entity.Productinfo;
import fr.sorbonne.soa.entity.Invoice;
import fr.sorbonne.soa.entity.Invoicedelaypenalty;
import fr.sorbonne.soa.entity.Shipperinfo;
import fr.sorbonne.soa.exception.ProductNotManufacturedException;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import java.util.UUID;
import javax.ejb.Stateless;
import javax.xml.ws.WebServiceRef;

import shippingprocessor.PenaltyWebServiceService;
import shippingprocessor.WebService4DistributorService;
import ws.Manufacturer2WSService;
import ws.Manufacturer3WSService;
import ws.Manufacturingorder;
/**
 *
 * @author Nairo
 */
@Stateless
public class ManagerDistributorBean implements ManagerDistributorLocal {
    @WebServiceRef(wsdlLocation = "META-INF/wsdl/client/Manufacturer2WS/192.168.0.23_8080/Manufacturer2WSService/Manufacturer2WS.wsdl")
    private Manufacturer2WSService manufacturer2WS;

    @WebServiceRef(wsdlLocation = "META-INF/wsdl/client/Manufacturer3WS/192.168.0.21_8080/Manufacturer3WSService/Manufacturer3WS.wsdl")
    private Manufacturer3WSService manufacturer3WS;

    //@WebServiceRef(wsdlLocation = "META-INF/wsdl/client/WebService4Distributor/192.168.0.21_8080/WebService4DistributorService/WebService4DistributorService.wsdl")
    //private WebService4DistributorService shipper1WS;

 //   @WebServiceRef(wsdlLocation = "META-INF/wsdl/client/WSDistributeurService/192.168.0.25_8080/WSDistributeurServiceService/WSDistributeurService.wsdl")
 //   private WSDistributeurService shipper2WS;

    //@WebServiceRef(wsdlLocation = "META-INF/wsdl/client/PenaltyWebService/192.168.0.21_8080/PenaltyWebServiceService/PenaltyWebService.wsdl")
    //private PenaltyWebServiceService penaltyWS;


    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method" or "Web Service > Add Operation"
    @EJB
    private ShipperinfoFacadeLocal shipperinfoFacade;
    @EJB
    private ProductinfoFacadeLocal productinfoFacade;
    @EJB
    private ManufacturerinfoFacadeLocal manufacturerinfoFacade;
    @EJB
    private InvoicedelaypenaltyFacadeLocal invoicedelaypenaltyFacade;
    @EJB
    private InvoiceFacadeLocal invoiceFacade;
    @EJB
    private CustomerorderFacadeLocal customerorderFacade;

    /**
     * Création d'une commande
     * @param p Produit commandé
     * @param qte quantité commandée
     */
    public void createOrder(Productinfo p, int qte) {
        String productTypeId = p.getProducttypeid();

        //Insertion dans customerorder
        Customerorder co = new Customerorder();
        //Génération de l'id
        String orderId = UUID.randomUUID().toString();
        co.setOrderid(orderId);
        co.setStatus("UNDER_PREP");
        co.setIspaid(0);
        
        List<Manufacturerinfo> list =  manufacturerinfoFacade.findManufacturerByProduct1(productTypeId);

        if(list.isEmpty()){
            list = manufacturerinfoFacade.findManufacturerByProduct2(productTypeId);
        }
        if(list.isEmpty()) {
            list = manufacturerinfoFacade.findManufacturerByProduct3(productTypeId);
        }

        if(list.isEmpty()) {
            //throw new ProductNotManufacturedException();
        } else {
            String manufacturerId = "";

            //On prend le premier manufacturer
            for(Manufacturerinfo m:list){
                manufacturerId = m.getManufacturerid();
                co.setManufacturer(m);
                break;
            }

            Manufacturingorder order = new Manufacturingorder();
            order.setAmount(co.getAmount());
            order.setQuantity(qte);
            order.setIspaid(co.getIspaid());
            
            if(manufacturerId.equals("m2")){
                manufacturer2WS.getManufacturer2WSPort().placeOrder(order);
            } else if (manufacturerId.equals("m3")) {
                manufacturer3WS.getManufacturer3WSPort().placeOrder(order);
            } else {
                //throw new Exception();
            }
        }


        String shippingConditions = p.getShippingconditions();
        List<Shipperinfo> listShipperInfo = shipperinfoFacade.findShipperByShippingConditions(shippingConditions);

        String shipperId = "";
        //On se positionne sur le premier shipper de la liste
        for (Shipperinfo si:listShipperInfo){
            shipperId = si.getShippingcompanyid();
            break;
        }

        //CHOIX DU SHIPPER SAUF QUE LA FONCTION
        //DE LEUR WEBSERVICE N'ATTEND PAS L'idShipper EN PARAMETRE --'
        if(shipperId.equals("s1")){
    //            shipper1WS.getWebService4DistributorPort().createShippingOrder(orderId, productTypeId, qte);
            } else if (shipperId.equals("s2")) {
                //shipper2WS.getWebService4DistributorPort().createShippingOrder(orderId, productTypeId, qte);
            } else {
                //throw new Exception();
            }
        
        customerorderFacade.create(co);
        //System.err.println("create order" + p.toString() + " / Qte : " + qte);
    }

    public void createShipperInvoice(InvoiceToDistributor invoice, Date estimatedShippingDate) {
        //Création de la nouvelle invoice
        Invoice newInvoice = new Invoice();
        newInvoice.setAmount(invoice.getAmount());
        newInvoice.setInvoiceid(invoice.getInvoiceid());
        newInvoice.setInvoicetype(invoice.getInvoicetype());
        newInvoice.setIspaid(invoice.getIspaid());
        newInvoice.setOrderid(invoice.getOrderid());

        //Récupération de la commande
        Customerorder co = customerorderFacade.find(invoice.getOrderid());
        co.setEstimateddelivery(estimatedShippingDate);

        invoiceFacade.create(newInvoice);
        customerorderFacade.edit(co);
    }

    public void createManufacturerInvoice(InvoiceToDistributor invoice, Date estimatedProductionStartDate) {
        //Création de la nouvelle invoice
        Invoice newInvoice = new Invoice();
        newInvoice.setAmount(invoice.getAmount());
        newInvoice.setInvoiceid(invoice.getInvoiceid());
        newInvoice.setInvoicetype(invoice.getInvoicetype());
        newInvoice.setIspaid(invoice.getIspaid());
        newInvoice.setOrderid(invoice.getOrderid());

        //Récupération de la commande
        Customerorder co = customerorderFacade.find(invoice.getOrderid());
        co.setEstimatedproductionstartdate(estimatedProductionStartDate);

        invoiceFacade.create(newInvoice);
        customerorderFacade.edit(co);

        //System.err.println("createManufacturerInvoice invoice : " + invoice.toString()
        //        + " / estimation : " + estimatedProductionStartDate.toString());
    }

    public void receivePayment(InvoiceToDistributor invoiceDistributor) {
        Invoice invoice = invoiceFacade.find(invoiceDistributor.getInvoiceid());
        invoice.setIspaid(1);
        
        invoiceFacade.edit(invoice);
        //System.err.println("receivePayment invoice : " + invoice.toString());
    }

    public void createShipperDelay(String orderId, Date newDeliveryDate) {
        Customerorder order = customerorderFacade.find(orderId);
        order.setEstimateddelivery(newDeliveryDate);

        customerorderFacade.edit(order);
        //System.err.println("createShipperDelay id : " + orderId + " / date : " + newDeliveryDate.toString());
    }

    public void setProductionDate(String orderId, Date productionDate) {
        Customerorder order = customerorderFacade.find(orderId);
        order.setEstimatedproductionstartdate(productionDate);

        customerorderFacade.edit(order);
        //System.err.println("setProductionDate id : " + orderId + " / date : " + productionDate.toString());
    }

    public void createInvoiceDelayPenalty(InvoiceDelayToDistributor invoice) {
        Invoicedelaypenalty invoiceDelayPenalty = new Invoicedelaypenalty();
        //Génération de l'id
        int penaltyInvoiceId = UUID.randomUUID().clockSequence();
        
        invoiceDelayPenalty.setPenaltyinvoiceid(penaltyInvoiceId);
        invoiceDelayPenalty.setAmount(invoice.getAmount());
        invoiceDelayPenalty.setInvoicetype(invoice.getInvoicetype());
        invoiceDelayPenalty.setIspaid(0);
        invoiceDelayPenalty.setOrderid(invoice.getOrderid());
        //Création de la penalité dans notre base
        invoicedelaypenaltyFacade.create(invoiceDelayPenalty);
        //System.err.println("createInvoiceDelayPenalty invoice : " + invoice.toString());
    }

    public void setOrderDelivered(String orderId) {
        Customerorder order = customerorderFacade.find(orderId);
        order.setStatus("SHIPPED");

        customerorderFacade.edit(order);
        //System.err.println("setOrderDelivered id : " + orderId);
    }

    public void createInvoiceShipperDelayPenalty(String orderId, Date dateDelay) {
        List<Invoice> listeInvoice = invoiceFacade.findInvoiceByOrderId(orderId, "SHIPPING");
        Invoice invoiceShipper = null;

        for(Invoice i:listeInvoice){
            invoiceShipper = i;
            break;
        }

        //Calcul de la penalité
        //Date dateDelivery = order.getEstimateddelivery();
        Double amount = invoiceShipper.getAmount();
        int nbJours = 5;
        amount = amount + (amount / 100) * nbJours;
        
        Invoicedelaypenalty invoicePenalty = new Invoicedelaypenalty();
        int penaltyInvoiceId = UUID.randomUUID().clockSequence();
        
        invoicePenalty.setPenaltyinvoiceid(penaltyInvoiceId);
        invoicePenalty.setInvoicetype("Ship_Penalty");
        invoicePenalty.setOrderid(orderId);
        invoicePenalty.setAmount(amount);
        invoicePenalty.setIspaid(0);
        
        invoicedelaypenaltyFacade.create(invoicePenalty);
    }

    public void receiveCustomerPayment(Customerorder order, Double amount){

        //Récupération de la commande
        Customerorder co = customerorderFacade.find(order.getOrderid());

        //On test si le montant correspond bien au montant de la facture
        if (co.getAmount() == amount){
            co.setIspaid(1);
            customerorderFacade.edit(co);
        } else {
            //prevoir exception
        }
    }

}
